from flask import Blueprint, request, render_template, redirect, url_for, jsonify, session
from datetime import datetime
import json
from sqlalchemy import func
from ollama import chat, ChatResponse

from models import db
from models import QuestionBank, Exam, Class, Teacher, Test2question, Test_paper, ExamClass, Answer, Student

correction = Blueprint('Correction', __name__)


@correction.route('/Correction/<int:exam_id>')
def correction_page(exam_id):
    """显示考试批改页面"""
    teacher_id = session.get('teacher_id', 1)
    print('跳转成功')

    # 获取考试信息
    exam = Exam.query.get(exam_id)
    if not exam:
        return render_template('404_final.html'), 404

    # 检查教师是否有权限批改此考试
    if exam.teacher_id != teacher_id:
        return render_template('403_final.html'), 403

    # 获取该考试的所有学生答案记录
    answers = Answer.query.filter_by(exam_id=exam_id).all()

    # 获取该考试唯一的学生列表
    students = {}
    for answer in answers:
        if answer.student_id not in students:
            # 获取学生信息
            student = Student.query.get(answer.student_id)
            students[answer.student_id] = {
                'id': student.id,
                'name': student.name,
                'class_id': student.class_id,
                'class_name': Class.query.get(student.class_id).class_name if Class.query.get(
                    student.class_id) else '未分配班级',
                'answers': [],
                'score': None,
            }
        students[answer.student_id]['answers'].append(answer)

    # 统计每个学生的总分
    for student_id, student_data in students.items():
        # 检查是否所有题目都已评分
        all_graded = all(answer.stu_score is not None for answer in student_data['answers'])
        if all_graded:
            # 计算总分
            total_score = sum(answer.stu_score for answer in student_data['answers'])
            student_data['score'] = total_score

    # 将学生字典转换为列表
    student_list = list(students.values())

    # 统计已提交和已批改数量
    submitted_count = len(student_list)
    graded_count = sum(1 for s in student_list if s['score'] is not None)

    return render_template(
        'Correction_new.html',
        exam=exam,
        students=student_list,
        submitted_count=submitted_count,
        graded_count=graded_count
    )


@correction.route('/grade_exam/<int:exam_id>/<int:student_id>')
def grade_exam(exam_id, student_id):
    """批改单个学生的考试答案"""
    # 检查教师是否登录
    teacher_id = session.get('teacher_id', 1)
    if not teacher_id:
        return redirect(url_for('index'))

    teacher = Teacher.query.get(teacher_id)
    if not teacher:
        return redirect(url_for('index'))

    # 获取考试信息
    exam = Exam.query.get(exam_id)
    if not exam:
        return render_template('404_final.html'), 404

    # 检查教师是否有权限批改此考试
    if exam.teacher_id != teacher.id:
        print('不是该教师')
        return render_template('403_final.html'), 403

    # 获取学生信息
    student = Student.query.get(student_id)
    if not student:
        print('没有学生记录')
        return render_template('404_final.html'), 404

    # 获取该学生该考试的所有答案记录
    from sqlalchemy import asc  # 导入升序排序的函数

    # ... 在你的函数中 ...

    student_answers = Answer.query.filter_by(
        exam_id=exam_id,
        student_id=student_id
    ).order_by(
        asc(Answer.question_id)  # 按照 question_id 升序排列
    ).all()

    # 获取要和学生对照的试卷里的题库答案，按照question_id 排好顺序方便和学生的答案表一一对应
    # 2. 从学生的答案列表中提取出所有的 question_id
    answered_question_ids = [ans.question_id for ans in student_answers]

    # 3. 检查学生是否真的回答了题目，避免查询空列表
    if not answered_question_ids:
        # 如果学生一道题都没答，那么题库列表就是空的
        question_rows = []
    else:
        # 4. 使用这些 ID 去查询 QuestionBank 表
        question_rows = (
            db.session.query(QuestionBank)
            .filter(QuestionBank.id.in_(answered_question_ids))  # <--- 核心修改在这里
            .order_by(QuestionBank.id.asc())  # <--- 按题号排序
            .all()
        )
    # 处理题目数据
    questions = []
    # 试卷和对应的题库信息
    for answer, question in zip(student_answers, question_rows):
        # 获取题目文本，优先使用QuestionBank表中的title 不健全
        question_text = question.title if question else str(answer.question_id)

        # 获取选项，优先使用Test_paper表中的选项
        option_payload = question.option if question else None
        final_options = []
        if option_payload:
            # 只有选择题和多选题才需要处理选项
            if question.type in ['选择题', '多选题']:
                try:
                    # 尝试解析JSON格式的选项
                    final_options = json.loads(option_payload)
                except:
                    # 如果不是JSON格式，尝试按|分割
                    final_options = [{"label": opt[0], "content": opt[2:]} for opt in option_payload.split('|') if opt]

        # 查找该题目的学生答案
        student_answer = None
        answer_record = None
        for ans in student_answers:
            if ans.question_id == answer.question_id:
                # 记录下学生的答案和整条记录
                # 答案字段
                raw_answer_from_db = ans.stu_answer  # 从数据库拿到的是原始字符串
                # 答案记录
                answer_record = ans

                # --- 核心修改在这里 ---
                # 尝试将 JSON 字符串解析回原始的 Python 对象
                try:
                    student_answer = json.loads(raw_answer_from_db)

                except (json.JSONDecodeError, TypeError):
                    # 如果解析失败（比如它本身就是一个普通字符串），就直接使用原始值
                    student_answer = raw_answer_from_db

                break

        questions.append({
            'id': answer.id,
            'question_id': answer.question_id,
            'question': question_text,
            'type': question.type,
            'options': final_options,
            'score': question.score if question else 0,
            'correct_answer': question.answer,
            'student_answer': student_answer,
            'answer_record_id': answer_record.id if answer_record else None,
            'current_score': answer_record.stu_score if answer_record else None,
        })

    # 计算总分
    total_score = sum(q['current_score'] for q in questions if q['current_score'] is not None)
    max_score = sum(int(q['score']) for q in questions if q['score'] is not None)

    # 检查是否所有题目都已评分
    all_graded = all(q['current_score'] is not None for q in questions)

    return render_template(
        'GradeExam.html',
        teacher=teacher,
        exam=exam,
        student=student,
        questions=questions,
        total_score=total_score,
        max_score=max_score,
        all_graded=all_graded
    )


@correction.route('/submit_grade/<int:exam_id>/<int:student_id>', methods=['POST'])
def submit_grade(exam_id, student_id):
    """提交批改结果"""
    # 检查教师是否登录
    # teacher_id = session.get('teacher_id')
    # if not teacher_id:
    #     return jsonify({'success': False, 'message': '未登录'}), 401
    #
    # # 获取考试信息
    # exam = Exam.query.get(exam_id)
    # if not exam or exam.teacher_id != teacher_id:
    #     return jsonify({'success': False, 'message': '无权限'}), 403

    # 获取学生信息
    student = Student.query.get(student_id)
    if not student:
        return jsonify({'success': False, 'message': '学生不存在'}), 404

    # 获取请求中的题目分数
    question_scores = request.json.get('question_scores', {})

    try:
        # 更新每道题的分数
        for question_id, score in question_scores.items():
            # 查找答案记录
            answer = Answer.query.filter_by(
                exam_id=exam_id,
                student_id=student_id,
                question_id=question_id
            ).first()

            if answer:
                answer.stu_score = float(score)

        db.session.commit()
        return jsonify({'success': True, 'message': '批改完成'})
    except Exception as e:
        db.session.rollback()
        return jsonify({'success': False, 'message': f'保存失败: {str(e)}'}), 500


@correction.route('/auto_grade/<int:exam_id>/<int:student_id>', methods=['POST'])
def auto_grade(exam_id, student_id):
    """自动批改选择题和多选题"""
    # 检查教师是否登录
    teacher_id = session.get('teacher_id', 1)

    if not teacher_id:
        return jsonify({'success': False, 'message': '未登录'}), 401

    # 获取考试信息
    exam = Exam.query.get(exam_id)
    if not exam:
        return jsonify({'success': False, 'message': '考试不存在'}), 404

    # 检查教师是否有权限批改此考试
    if exam.teacher_id != teacher_id:
        return jsonify({'success': False, 'message': '无权限批改此考试'}), 403

    # 获取该学生的所有答案
    answers = Answer.query.filter_by(exam_id=exam_id, student_id=student_id).all()
    answer_question_ids = [answer.question_id for answer in answers]

    # 获取试卷题目信息
    question_rows = (
        db.session.query(QuestionBank)
        .filter(QuestionBank.id.in_(answer_question_ids))  # 修复语法错误
        .order_by(QuestionBank.id)
        .all()
    )
    test_paper_records = (
        db.session.query(Test_paper)
        .filter(Test_paper.question_id.in_(answer_question_ids))
        .order_by(Test_paper.question_id)
        .all()
    )

    # 创建试卷题目字典，便于查找正确答案
    test_paper_dict = {record.question_id: record for record in test_paper_records}

    # 创建答案字典，便于查找
    answer_dict = {ans.question_id: ans for ans in answers}

    try:
        # 自动批改选择题和多选题
        processed_count = 0
        for question in question_rows:
            # 只处理选择题和多选题
            if question.type not in ['选择题', '多选题']:
                continue

            # 获取学生答案记录
            answer_record = answer_dict.get(question.id)
            if not answer_record:
                continue

            # 如果已经评分，则跳过
            # if answer_record.stu_score is not None:
            #     continue

            # 获取试卷中的正确答案
            test_paper_record = test_paper_dict.get(question.id)
            if not test_paper_record:
                continue

            # 解析学生答案（可能是JSON格式）
            student_answer = answer_record.stu_answer  # 修复：使用stu_answer而不是answer
            try:
                student_answer = json.loads(student_answer)
            except (json.JSONDecodeError, TypeError):
                # 如果解析失败，使用原始值
                pass

            # 获取正确答案
            correct_answer = test_paper_record.answer

            # 判断答案是否正确
            if student_answer == str(correct_answer).strip():
                answer_record.stu_score = test_paper_record.score  # 修复：使用stu_score而不是score
                answer_record.num = 0
                processed_count += 1
            else:
                answer_record.stu_score = 0  # 修复：使用stu_score而不是score
                answer_record.num = 2
                processed_count += 1

        db.session.commit()

        # 重新获取答案和题目信息，构建与grade_exam相同格式的数据
        updated_student_answers = Answer.query.filter_by(
            exam_id=exam_id,
            student_id=student_id
        ).order_by(Answer.question_id).all()

        # 重新获取题目信息
        updated_question_rows = (
            db.session.query(QuestionBank)
            .filter(QuestionBank.id.in_([ans.question_id for ans in updated_student_answers]))
            .order_by(QuestionBank.id)
            .all()
        )

        # 获取试卷信息
        updated_test_paper_records = (
            db.session.query(Test_paper)
            .filter(Test_paper.question_id.in_([ans.question_id for ans in updated_student_answers]))
            .order_by(Test_paper.question_id)
            .all()
        )
        updated_test_paper_dict = {record.question_id: record for record in updated_test_paper_records}

        # 构建问题数据
        questions = []
        for answer, question in zip(updated_student_answers, updated_question_rows):
            # 获取题目文本
            question_text = question.title if question else str(answer.question_id)

            # 获取选项
            option_payload = question.option if question else None
            final_options = []
            if option_payload and question.type in ['选择题', '多选题']:
                try:
                    final_options = json.loads(option_payload)
                except:
                    final_options = [{"label": opt[0], "content": opt[2:]} for opt in option_payload.split('|') if opt]

            # 获取学生答案
            student_answer = None
            try:
                student_answer = json.loads(answer.stu_answer)
            except (json.JSONDecodeError, TypeError):
                student_answer = answer.stu_answer

            # 获取正确答案
            test_paper = updated_test_paper_dict.get(answer.question_id)
            correct_answer = test_paper.answer if test_paper else (question.answer if question else "")

            # 判断答案是否正确
            is_correct = None  # 填空题和简答题不直接判断对错

            questions.append({
                'id': answer.id,
                'question_id': answer.question_id,
                'question': question_text,
                'type': question.type,
                'options': final_options,
                'score': test_paper.score if test_paper else (question.score if question else 0),
                'correct_answer': correct_answer,
                'student_answer': student_answer,
                'answer_record_id': answer.id,
                'current_score': answer.stu_score,
                'is_correct': is_correct
            })

        # 计算总分
        total_score = sum(q['current_score'] for q in questions if q['current_score'] is not None)
        max_score = sum(float(q['score']) for q in questions if q['score'] is not None)

        # 检查是否所有题目都已评分
        all_graded = all(q['current_score'] is not None for q in questions)

        message = f"自动批改完成，已处理{processed_count}道选择题和多选题" if processed_count > 0 else "没有找到需要批改的选择题和多选题"
        return jsonify({
            'success': True,
            'message': message,
            'questions': questions,
            'total_score': total_score,
            'max_score': max_score,
            'all_graded': all_graded
        })
    except Exception as e:
        db.session.rollback()
        print(f"自动批改出错: {str(e)}")
        return jsonify({'success': False, 'message': f'自动批改失败: {str(e)}'}), 500

#调试不要动
# import ollama
# import torch
# import os
# from transformers import AutoTokenizer, AutoModel, AutoModelForCausalLM
# from langchain_community.vectorstores import Chroma
# # 在文件顶部，把上面那行改成这行
# from langchain_huggingface import HuggingFaceEmbeddings
# from langchain_core.documents import Document
#
# # 设置离线模式环境变量
# os.environ["TRANSFORMERS_OFFLINE"] = "1"
# os.environ["HF_DATASETS_OFFLINE"] = "1"
#
# # 尝试使用本地模型，如果失败则使用更简单的替代方案
# try:
#     model_name = "sentence-transformers/all-MiniLM-L12-v2"
#     # 指定本地缓存目录
#     cache_dir = "model_cache"
#
#     # 尝试加载嵌入模型
#     embedding_model = HuggingFaceEmbeddings(
#         model_name=model_name,
#         cache_folder=cache_dir
#     )
#     tokenizer = AutoTokenizer.from_pretrained(model_name, cache_dir=cache_dir)
#     model = AutoModel.from_pretrained(model_name, cache_dir=cache_dir)
#
#     gen_model_name = "HuggingFaceTB/SmolLM2-135M"
#     gen_tokenizer = AutoTokenizer.from_pretrained(gen_model_name, trust_remote_code=True, cache_dir=cache_dir)
#     gen_model = AutoModelForCausalLM.from_pretrained(gen_model_name, trust_remote_code=True, cache_dir=cache_dir)
#
#     MODEL_LOADED = True
# except Exception as e:
#     print(f"无法加载模型: {e}")
#     print("将使用简化版本的评分功能")
#     MODEL_LOADED = False
#
#     # 创建空的占位对象，避免代码中引用错误
#     embedding_model = None
#     tokenizer = None
#     model = None
#     gen_tokenizer = None
#     gen_model = None
# from pathlib import Path

# KNOWLEDGE_BASE_DIR = Path("MY_kenwledge")
# import os
#
# api_key = os.getenv("OLLAMA_API_KEY")


def extract_text(query: str) -> str:
    """
    根据查询关键词从知识库中检索相关文档内容。
    这是一个简单的关键词匹配检索。
    """
    context = ""
    # 确保知识库目录存在
    if not KNOWLEDGE_BASE_DIR.is_dir():
        print(f"警告：知识库目录 '{KNOWLEDGE_BASE_DIR}' 不存在。")
        return ""

    # 将查询词转换为小写，以便进行不区分大小写的匹配
    query_lower = query.lower()

    # 遍历知识库中的所有.txt文件
    for path in KNOWLEDGE_BASE_DIR.glob("*.txt"):
        # 检查文件名（不含扩展名）是否是查询词的子字符串
        try:
            context += path.read_text(encoding="utf-8")
            context += "\n\n"
        except Exception as e:
            print(f"读取文件 {path.name} 时出错: {e}")

    return context


def generate_embedding(docs, model, tokenizer):
    """返回整个句子的嵌入表示"""
    if not MODEL_LOADED or model is None or tokenizer is None:
        # 如果模型未加载，返回简单的基于哈希的嵌入作为替代
        import numpy as np
        # 使用简单的哈希函数生成固定长度的向量
        embeddings = []
        for doc in docs:
            # 创建一个简单的基于文本哈希的向量
            hash_val = hash(doc) % (2 ** 32)  # 限制哈希值范围
            vec = np.zeros(384)  # 与all-MiniLM-L12-v2的输出维度相同
            # 用哈希值填充向量
            for i in range(384):
                vec[i] = (hash_val >> (i % 8)) % 256 / 255.0
            embeddings.append(vec)
        return np.array(embeddings)

    # inputs 包括三个部分 embeding,attention_mask,padding_mask
    inputs = tokenizer(docs, padding=True, truncation=True, return_tensors="pt", max_length=512)
    with torch.no_grad():
        outputs = model(**inputs)  # 输出中包含了对句子的理解。

    # 与sentence-transformers的 pooling方式保持一致
    attention_mask = inputs["attention_mask"]
    embeddings = outputs.last_hidden_state

    # 计算[CLS]标记的嵌入，这是sentence-transformers的默认方式
    if attention_mask is not None:
        cls_embeddings = embeddings[:, 0, :]  # 取第一个标记的嵌入，BERT模型将[CLS]作为代表整个语句的语义。
        return cls_embeddings.cpu().numpy()
    else:
        return embeddings.mean(dim=1).cpu().numpy()  # 否则将seq取平均作为整个句子的语义。


def retrieve_documents(query, chroma_db, k=3):
    if not MODEL_LOADED or chroma_db is None:
        # 如果模型未加载，返回空结果
        return []

    # 每个句子的大体语义
    query_embedding = generate_embedding([query], model, tokenizer)[0]
    # 使用Chroma检索，去数据库找到相似性最高的块
    retrieved_docs = chroma_db.similarity_search_by_vector(
        embedding=query_embedding,
        k=k
    )
    # 提取文档内容和计算距离
    results = []
    for doc in retrieved_docs:
        doc_embedding = generate_embedding([doc.page_content], model, tokenizer)[0]
        distance = torch.nn.functional.pairwise_distance(
            torch.tensor(query_embedding).unsqueeze(0),
            torch.tensor(doc_embedding).unsqueeze(0)
        ).item()
        results.append((doc.page_content, distance))
    return results


# api_key = os.getenv("OLLAMA_API_KEY")
# if not api_key:
#     raise ValueError("错误：未找到环境变量 OLLAMA_API_KEY。请设置它。")


# 构建提示词
def augment_prompt(query: str, context: str) -> str:
    """
    根据检索到的上下文来增强用户的问题，生成一个更完整的提示词。
    """
    if not context:
        # 如果没有检索到上下文，让模型直接回答
        return f"请直接回答以下问题：\n\n问题：{query}"
    else:
        # 如果有上下文，则要求模型基于上下文回答
        return f"""
你是一个有着多年改卷经验的老师。请根据下面提供的上下文信息对学生的试题和答案参考上下文信息给出一个客观的得分,返回结果严格按照整形格式，不能出现其他字符。
你的回答必须严格基于上下文。如果上下文中没有足够的信息来回答问题，请明确回答"根据提供的上下文，我无法回答这个问题。"

---
上下文信息：
{context}
---

用户问题：
{query}

请根据上下文回答问题：
"""


def generate_response(query, docs, max_length=150):
    """
        query:  查询语句
        retrieved_docs:  检索到的文档列表
        max_length:  生成的最大长度
    """
    try:
        prompt = augment_prompt(query, docs)
        response: ChatResponse = chat(model='qwen2.5:7b', messages=[
            {'role': 'user',
             'content': prompt
             }
        ], options={'temperature': 0.1
                    })
        return response.message.content
    except Exception as e:
        return f"调用API时发生错误: {e}"

    return


# 找到最接近的话
def rag_pipeline(query, chroma_db, retriever_k=3, max_length=150):
    if not MODEL_LOADED:
        # 如果模型未加载，返回一个默认分数
        print('模型未加载')
        return "5"  # 默认中等分数

    retrieved_docs = retrieve_documents(query, chroma_db, k=retriever_k)  # 返回为 (doc, distance) 的列表
    if not retrieved_docs:
        # 如果没有检索到相关文档，返回默认分数
        print('没有检索到相关文档')
        return "5"

    docs = [doc for doc, distance in retrieved_docs]
    response = generate_response(query, docs, max_length=max_length)
    return response


# 自动批改填空题和简答题
@correction.route('/auto_text_grade/<int:exam_id>/<int:student_id>', methods=['POST'])
def auto_text_grade(exam_id, student_id):
    # 检查教师是否登录
    teacher_id = session.get('teacher_id', 1)

    if not teacher_id:
        return jsonify({'success': False, 'message': '未登录'}), 401

    # 获取考试信息
    exam = Exam.query.get(exam_id)
    if not exam:
        return jsonify({'success': False, 'message': '考试不存在'}), 404

    # 检查教师是否有权限批改此考试
    if exam.teacher_id != teacher_id:
        return jsonify({'success': False, 'message': '无权限批改此考试'}), 403

    # 获取该学生的所有答案
    answers = Answer.query.filter_by(exam_id=exam_id, student_id=student_id).all()
    answer_question_ids = [answer.question_id for answer in answers]

    # 构建知识库
    exam = Exam.query.get(exam_id)
    if not exam:
        return jsonify({'success': False, 'message': '考试不存在'}), 404

    exam_name = exam.name
    documents = [Document(page_content=text) for text in extract_text(exam_name)]

    # 只有在模型成功加载时才创建向量数据库
    chroma_db = None
    if MODEL_LOADED and documents:
        try:
            # 设置本地数据库
            chroma_db = Chroma.from_documents(
                documents=documents,
                embedding=embedding_model,
                persist_directory="chroma_db_v1"
            )
        except Exception as e:
            print(f"创建向量数据库失败: {e}")
            chroma_db = None

    # 获取试卷题目信息
    question_rows = (
        db.session.query(QuestionBank)
        .filter(QuestionBank.id.in_(answer_question_ids))  # 修复语法错误
        .order_by(QuestionBank.id)
        .all()
    )

    # 创建答案字典，便于查找
    answer_dict = {ans.question_id: ans for ans in answers}
    question_dict = {question.id: question for question in question_rows}

    # 从Test_paper表获取正确答案
    test_paper_records = (
        db.session.query(Test_paper)
        .filter(Test_paper.question_id.in_(answer_question_ids))
        .order_by(Test_paper.question_id)
        .all()
    )
    test_paper_dict = {record.question_id: record for record in test_paper_records}

    try:
        # 自动批改填空题和简答题
        processed_count = 0
        for answer in answers:
            # 获取对应的题目信息
            question = question_dict.get(answer.question_id)
            # 只处理填空题和简答题
            if question.type not in ['填空题', '简答题']:
                continue

            # 获取正确答案和学生答案
            test_paper = test_paper_dict.get(answer.question_id)
            correct_answer = test_paper.answer if test_paper else ""
            student_answer = answer.stu_answer if answer.stu_answer else ""

            # 使用RAG系统评分，提供更详细的上下文
            try:
                # 构建更详细的评分提示
                max_score = float(
                    test_paper.score if test_paper and test_paper.score else (question.score if question.score else 0))

                # 根据题目类型提供不同的评分标准
                if question.type == '填空题':
                    grading_rules = """
                    评分标准（0-{max_score}分）：
                    1. 完全正确：{max_score}分
                    2. 完全错误：0分

                    请只返回一个0-{max_score}之间的数字。
                    """.format(max_score=max_score, partial_score=max_score * 0.6)
                else:  # 简答题
                    grading_rules = """
                    评分标准（0-{max_score}分）：
                    1. 回答完整准确，包含所有关键点：{full_score}分
                    2. 回答基本正确，但缺少部分关键点：{partial_score1}分
                    3. 回答部分相关，但存在明显错误：{partial_score2}分
                    4. 回答不相关或完全错误：0分

                    请只返回一个0-{max_score}之间的数字。
                    """.format(
                        max_score=max_score,
                        full_score=max_score,
                        partial_score1=max_score * 0.7,
                        partial_score2=max_score * 0.3
                    )

                query = f"""
                请根据以下信息进行评分：

                题目类型：{question.type}
                题目：{question.title}
                参考答案：{correct_answer}
                学生答案：{student_answer}

                {grading_rules}

                请分析学生答案并给出0-{max_score}分之间的分数，只返回数字：
                """

                # 获取模型响应
                response_score = rag_pipeline(query, chroma_db)
                print(f"RAG系统评分结果: {response_score}")

                # 更健壮的分数提取
                try:
                    # 尝试从响应中提取数字
                    import re
                    score_match = re.search(r'\b\d+(\.\d+)?\b', response_score)

                    if score_match:
                        score = float(score_match.group())
                        # 确保分数在合理范围内
                        score = max(0, min(max_score, score))
                        answer.stu_score = round(score, 2)  # 保留两位小数
                        print(f"题目ID {answer.question_id}: 学生 {student_id} 得分 {answer.stu_score}/{max_score}")
                    else:
                        raise ValueError("未找到有效分数")

                except (ValueError, TypeError) as e:
                    print(f"分数解析错误: {e}, 原始响应: {response_score}")
                    # 使用更智能的默认分数策略
                    if '部分' in response_score or '部分正确' in response_score:
                        # 如果回答部分正确，给予一半分数
                        answer.stu_score = round(max_score * 0.5, 2)
                        print(f"题目ID {answer.question_id}: 学生 {student_id} 得分 {answer.stu_score}/{max_score} (部分正确)")
                    else:
                        # 其他情况给予0分
                        answer.stu_score = 0
                        print(f"题目ID {answer.question_id}: 学生 {student_id} 得分 {answer.stu_score}/{max_score} (无法解析分数)")
                    
            except Exception as e:
                print(f"处理题目ID {answer.question_id}时发生错误: {e}")
                answer.stu_score = 0
                    
            processed_count += 1
            

            
    except Exception as e:
        db.session.rollback()
        return jsonify({
                'success': False, 
                'message': f'批改过程中发生错误: {str(e)}'
        }), 500
    # 提交更改到数据库
    db.session.commit()
    return jsonify({
            'success': True,
            'message': f'成功批改{processed_count}道题目'
    })
